/****************************************************
	文件：Lighting.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/9/13 21:45:4
	功能：直接光
*****************************************************/

using System;
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Collections;

namespace LearningSRP
{
    public class Lighting
    {
        /// <summary>
        /// 缓冲名称
        /// </summary>
        private const string BufferName = "Lighting";
        /// <summary>
        /// 命令缓冲
        /// </summary>
        private CommandBuffer mBuffer = new CommandBuffer { name = BufferName };
        /// <summary>
        /// 裁剪结果
        /// </summary>
        private CullingResults mCullingResults;

        /// <summary>
        /// 最大直接光数量
        /// </summary>
        private const int MAX_DIRECTIONAL_LIGHT_COUNT = 4;

        private static int mDirLightCountId = Shader.PropertyToID("_DirectionalLightCount");
        private static int mDirLightColorsId = Shader.PropertyToID("_DirectionalLightColors");
        private static int mDirLightDirectionsId = Shader.PropertyToID("_DirectionalLightDirections");

        private static Vector4[] mDirLightColors = new Vector4[MAX_DIRECTIONAL_LIGHT_COUNT];
        private static Vector4[] mDirLightDirections = new Vector4[MAX_DIRECTIONAL_LIGHT_COUNT];

        public void Setup(ScriptableRenderContext context, CullingResults cullingResults)
        {
            mCullingResults = cullingResults;
            mBuffer.BeginSample(BufferName);
            SetupLights();
            mBuffer.EndSample(BufferName);
            context.ExecuteCommandBuffer(mBuffer);
            mBuffer.Clear();
        }
        /// <summary>
        /// 设置光线数据
        /// </summary>
        private void SetupLights()
        {
            NativeArray<VisibleLight> visibleLights = mCullingResults.visibleLights; //获取裁剪后的可见光
            int dirLightCount = 0;
            for (int i = 0; i < visibleLights.Length; i++)
            {
                VisibleLight visibleLight = visibleLights[i];
                if (visibleLight.lightType == LightType.Directional)
                {
                    SetupDirectionalLight(dirLightCount++, ref visibleLight);
                    if (dirLightCount >= MAX_DIRECTIONAL_LIGHT_COUNT) //最大直接光限制
                    {
                        break;
                    }
                }
            }
            //Light light = RenderSettings.sun;
            mBuffer.SetGlobalInt(mDirLightCountId, dirLightCount); //设置 直接光源数量
            mBuffer.SetGlobalVectorArray(mDirLightColorsId, mDirLightColors); //设置 直接光颜色
            mBuffer.SetGlobalVectorArray(mDirLightDirectionsId, mDirLightDirections); //设置 直接光方向
        }

        private void SetupDirectionalLight(int index, ref VisibleLight visibleLight)
        {
            mDirLightColors[index] = visibleLight.finalColor;
            mDirLightDirections[index] = -visibleLight.localToWorldMatrix.GetColumn(2);
        }
    }
}
